#include "ghost.h"
#include "ghostskill.h"
#include <QDebug>

using namespace Qt;
//------------------------------------//
// Ghost
//------------------------------------//

Ghost::Ghost(
        GhostManager* parent,
        QString path, QString name, int id, GSColor color,
        GhostSkills skill_l, GhostSkills skill_m, GhostSkills skill_r,
        int resist0, int resist1, int resist2, int resist3, int resist4,
        bool boss, bool buddha
        )
    : QObject(parent),
      _imgpath(path), _ghostname(name), _ghostid(id),_color(color),
      _skill_l(skill_l), _skill_m(skill_m), _skill_r(skill_r),
      _resist0(resist0), _resist1(resist1),
      _resist2(resist2), _resist3(resist3),_resist4(resist4),
      _boss(boss), _buddha(buddha)
{
    if( parent )
    {
        GameTable * table = parent->getTable();
        _skill_obj_l = GhostSkillFactory::createGhostSkillList( _skill_l, this, table );
        _skill_obj_m = GhostSkillFactory::createGhostSkillList( _skill_m, this, table );
        _skill_obj_r = GhostSkillFactory::createGhostSkillList( _skill_r, this, table );
        _ghostboard = NULL;
    }
}

void Ghost::exocise()
{
    _skill_obj_l->exo_actions();
    _skill_obj_r->invoke_all();
}

QString Ghost::ColorToString( GSColor c )
{
    switch( c )
    {
    case RED:
        return tr("red");
    case YELLOW:
        return tr("yellow");
    case GREEN:
        return tr("green");
    case BLUE:
        return tr("blue");
    case BLACK:
        return tr("black");
    case WHITE:
        return tr("white");
    }
    return tr("Not defined");
}

GlobalColor Ghost::ColorToQColor( GSColor c )
{
    switch( c )
    {
    case RED:
        return red;
    case YELLOW:
        return yellow;
    case GREEN:
        return green;
    case BLUE:
        return blue;
    case BLACK:
        return black;
    case WHITE:
        return white;
    }
    return white;
}

QString Ghost::SkillsToString( GhostSkills s )
{
    QString res = "";
    if( s.testFlag( NO_SKILL ) )
        return QString( " No Skill " );
    if( s.testFlag( ONE_MORE_CARD ) )
        res += " + One more card";

    if( s.testFlag( INSTANT_HAUNT ) )
        res += " + One more card";

    if( s.testFlag( CURSE_DICE ) )
        res += " + Curse dice";

    if( s.testFlag( LOSE_QI ) )
        res += " + Lose one Qi";

    if( s.testFlag( GHOSTS_MARCH ) )
        res += " + Ghost march";

    if( s.testFlag( SEAL_SKILLS ) )
        res += " + Seal skills";

    if( s.testFlag( HAUNTER ) )
        res += " + Haunter";

    if( s.testFlag( QI ) )
        res += " + Reward one Qi";

    if( s.testFlag( YINYANG ) )
        res += " + Reward Yinyang";

    if( s.testFlag( TAO ) )
        res += " + One Tao token";
    return res;
}


//------------------------------------//
// GhostManager
//------------------------------------//

GhostManager * GhostManager::_ghostmanager = 0;

GhostManager::GhostManager( GameTable * table, QObject * parent )
    : QObject( parent )
{
    _table = table;
    _ghostcount = 0;
}

void GhostManager::add( Ghost* ghost )
{
    if( ghost->isBoss() )
        _bglist << ghost ;
    else
        _tglist << ghost;
    _ghostcount ++;
}


// get a deck of cards for playing.
// The pattern of ghost deck is:
//   _trash_ trash cards, then 1 boss card, repeat for _rounds_ rounds
//
// shuffle the lists if it is true
QList <Ghost*> GhostManager::getList( int rounds, int trash, bool shuffle )
{
    QList <Ghost*> res;
    if( shuffle )
    {
        int k, ts = 0, bs = 0;
        for( int i = 0; i < rounds; i ++ )
        {
            for( int j = 0; j < trash; j ++ )
            {
                // random a trash ghost from trash list
                // it should have not appeared in the list yet
                while( ts < _tglist.count() )
                {
                    k = qrand() % _tglist.count();
                    if( !res.contains( _tglist.at( k ) ) )
                    {
                        res << _tglist.at( k ) ;
                        ts ++;
                        break;
                    }
                }
            }
            // random a boss ghost from trash list
            // it should have not appeared in the list yet
            while( bs < _bglist.count() )
            {
                k = qrand() % _bglist.count();
                if( !res.contains( _bglist.at( k ) ) )
                {
                    res << _bglist.at( k ) ;
                    bs ++;
                    break;
                }
            }
            // if there are still trashes left.
            while( ts < _tglist.count() )
            {
                k = qrand() % _tglist.count();
                if( !res.contains( _tglist.at( k ) ) )
                {
                    res << _tglist.at( k ) ;
                    ts ++;
                }
            }
        }
    }
    else
    {
        for( int i = 0; i < rounds; i ++ )
        {
            for( int j = 0; j < trash; j ++ )
            {
                if( i * trash + j > _tglist.length() - 1 )
                    break;
                res << _tglist.at( i * trash + j );
            }
            res << _bglist.at( i );
        }
    }
    return res;
}

void GhostManager::CreateManager( GameTable * table )
{
    if ( _ghostmanager )
    {
        return;
    }
    GhostManager *gm = new GhostManager( table );
    Ghost *ghost0 = new Ghost( gm, tr(":/common/images/bghost0.jpg"),
                               tr("Girl"), 0, BLACK,
                               ONE_MORE_CARD, CURSE_DICE, INSTANT_HAUNT,
                               3, 2, 3, 0, 0, true, true );
    Ghost *ghost1 = new Ghost( gm, tr(":/common/images/tghost0.jpg"),
                               tr("Zhang San"), 1, RED,
                               NO_SKILL, HAUNTER, LOSE_QI,
                               0, 1, 3, 0, 0, false, false );
    Ghost *ghost2 = new Ghost( gm, tr(":/common/images/tghost1.jpg"),
                               tr("Li Si"), 2, BLUE,
                               NO_SKILL, CURSE_DICE, ONE_MORE_CARD,
                               1, 0, 0, 0, 0, false, false );
    Ghost *ghost3 = new Ghost( gm, tr(":/common/images/tghost2.jpg"),
                               tr("Chun Ge"), 3, BLUE,
                               INSTANT_HAUNT, NO_SKILL, TAO,
                               0, 0, 2, 0, 0, false, false );
    Ghost *ghost4 = new Ghost( gm, tr(":/common/images/tghost3.jpg"),
                               tr("Cao Nima"), 4, BLUE,
                               NO_SKILL, HAUNTER, TAO,
                               0, 0, 0, 0, 3, false, false );
    Ghost *ghost5 = new Ghost( gm, tr(":/common/images/tghost4.jpg"),
                               tr("Spring Bro."), 5, BLUE,
                               ONE_MORE_CARD, NO_SKILL, TAO,
                               0, 0, 0, 4, 0, false, false );
    Ghost *ghost6 = new Ghost( gm, tr(":/common/images/bghost1.jpg"),
                               tr("Mage"), 6, RED,
                               DICE_HOLDER, HAUNTER, QI | YINYANG,
                               0, 0, 2, 0, 2, true, true );

    gm->add( ghost0 );
    gm->add( ghost1 );
    gm->add( ghost2 );
    gm->add( ghost3 );
    gm->add( ghost4 );
    gm->add( ghost5 );
    gm->add( ghost6 );

    _ghostmanager = gm;
}



/* return a TestManager for testing purpose */
GhostManager * GhostManager::GetManager()
{
    if ( _ghostmanager )
        return _ghostmanager;
    else
        return NULL;
}


Ghost *GhostManager::DefaultGhost()
{
    Ghost *res = new Ghost( GetManager(), tr(":/common/images/unknown.png"),
                            tr("N/A"), -1, WHITE,
                            NO_SKILL, NO_SKILL, NO_SKILL );
    return res;
}

